﻿<html>
<head>
<meta charset=UTF-8">
<title>WebSocket读卡测试</title>
</head>
<body bgcolor="#D2F0FF">
	<h1 style="text-align:center;color:#5555FF;">身份证阅读器WebSocket接入测试页面</h1>
		<input id="url" type="text" value="ws://127.0.0.1:18890" style="width:500px"/>
    <button onclick="openWebSocket()">打开WebSocket连接</button>
    <button onclick="closeWebSocket()">关闭WebSocket连接</button>
	<h3>当前消息</h3>    
	<button onclick="clearMsg()">清除</button>
  <div id="message"></div>
</br>

<table border="0" width="50%" cellpadding="0" cellspacing="0" style="padding-left:100px;">
    <tr>
        <td><input type="button" value="连接设备" onclick="connect()"></td>
        <td><input type="button" value="状态" onclick="getStatus()"></td>
        <td><input type="button" value="读卡(不合成照片)" onclick="readCard()"></td>
        <td><input type="button" value="读卡(合成照片)" onclick="readCert()"></td>
        <td><input type="button" value="断开" onclick="disconnect()"></td>
		<td><input type="button" value="读IC卡序列号" onclick="readICCardSN()"></td>
		<td><input type="button" value="读身份证物理卡号" onclick="readIDCardSN()"></td>
		<td><input type="button" value="读安全模块号" onclick="getSAMID()"></td>
		<td><input type="button" value="开启推送(带图片)" onclick="startPushInfosWithImg()"></td>
		<td><input type="button" value="开启推送(不带图片)" onclick="startPushInfosWithOutImg()"></td>
		<td><input type="button" value="关闭推送" onclick="stopPushInfos()"></td>
		<td><input type="button" value="允许重复读卡" onclick="enableRepeatRead()"></td>
		<td><input type="button" value="禁止重复读卡" onclick="disableRepeatRead()"></td>
		<td><input type="button" value="关闭读卡提示音" onclick="Routon_Mute()"></td>
		<td><input type="button" value="开启读卡提示音" onclick="Routon_UnMute()"></td>
		<td><input type="button" value="开启连接状态检测" onclick="startCheckStatus()"></td>
		<td><input type="button" value="关闭连接状态检测" onclick="stopCheckStatus()"></td>
	</tr>
</table>
<br/>
<table border="0" width="100%" cellpadding="0" cellspacing="10">
    <tr>
        <td align="right">读卡时间：</td>
        <td><input type="text" id="timeElapsed" size="49" style="width:400px;" readonly="readonly"></td>
    </tr>
    <tr>
        <td align="right">数字签名：</td>
        <td><input type="text" id="signature" size="49" style="width:400px;" readonly="readonly"></td>
    </tr>
    <tr>
        <td align="right">厂家标识：</td>
        <td><input type="text" id="venderId" size="49" style="width:400px;" readonly="readonly"></td>
    </tr>
    <td align="right">卡类型：</td>
    <td><input type="text" id="certType" size="49" style="width:400px;" readonly="readonly">(1-中国居民身份证，50-外国人永久居住证证，54-台湾居住证，55-港澳居住证)
    </td>
    </tr>
    <tr>
        <td align="right">中/英姓名：</td>
        <td><input type="text" id="partyName" size="49" style="width:400px;" readonly="readonly">(要求中间，两头都没有空格)</td>
    </tr>
    <tr>
        <td align="right">性别：</td>
        <td><input type="text" id="gender" size="49" style="width:400px;" readonly="readonly">(取值为“1”（表示“男”）或“0”（表示“女”）)
        </td>
    </tr>
    <tr>
        <td align="right">民族/国籍：</td>
        <td><input type="text" id="nation" size="49" style="width:400px;" readonly="readonly">(汉字即可)</td>
    </tr>
    <tr>
        <td align="right">出生日期：</td>
        <td><input type="text" id="bornDay" size="49" style="width:400px;" readonly="readonly">(要求格式为:yyyyMMdd，长度为8)
        </td>
    </tr>
    <tr>
        <td align="right">住址：</td>
        <td><input type="text" id="certAddress" size="49" style="width:400px;" readonly="readonly">(外国人永久居留身份证地址为“空”)
        </td>
    </tr>
    <tr>
        <td align="right">身份证号：</td>
        <td><input type="text" id="certNumber" size="49" style="color:#FF0000;width:400px;" readonly="readonly">(居民身份号码，长度18位)
        </td>
    </tr>
    <tr>
        <td align="right">签发机关：</td>
        <td><input type="text" id="certOrg" size="49" style="width:400px;" readonly="readonly">(外国永久居留身份证签发机关为“机关代码”)
        </td>
    </tr>
    <tr>
        <td align="right">开始期限：</td>
        <td><input type="text" id="effDate" size="49" style="width:400px;" readonly="readonly">(要求格式为:yyyyMMdd，长度为8)
        </td>
    </tr>
    <tr>
        <td align="right">结束期限：</td>
        <td><input type="text" id="expDate" size="49" style="width:400px;" readonly="readonly">(要求格式为:yyyyMMdd，长度为8，或者是“长期”)
        </td>
    </tr>
    <tr>
        <td align="right">照片：</td>
        <td><img id="HeadPic" style="height: 126px; width: 102px" align="top" />
    </tr>
	<tr>
		<td>预览：</td>
		<td><img id="PhotoDisplay" style="width:341px; height:443px;"/></td>
		<td>正面：</td>
		<td><img id="FrontPic" style="width:341px; height:222px;"/></td>
		<td>背面：</td>
		<td><img id="BackPic" style="width:341px; height:222px;"/></td>
	</tr>
</table>
<br>
<br>
<table border="0" width="100%" cellpadding="0" cellspacing="10">
	 <tr>
        <!--td align="right"">扇区号：</td>
        <td><input type="text" id="sid" size="49" style="width:50px;"></td>
		<td align="right">块号：</td>
        <td><input type="text" id="bid" size="49" style="width:50px;"></td>
		<td align="right">密钥类型：</td>
        <td><input type="text" id="keyType" size="49" style="width:50px;"></td>
		<td align="right">密钥：</td>
        <td><input type="text" id="key" size="49" style="width:100px;"></td-->
		<td>
			扇区号（SID）：<input type="text" style="width:60px;hidth:30px" id="input_sid" onkeyup="value=value.replace(/\D/g,'')" oncontextmenu="return false;" onblur="valid('input_sid',15)">
			块号（BID）：<input type="text" style="width:60px;hidth:30px" id="input_bid" onkeyup="value=value.replace(/\D/g,'')" oncontextmenu="return false;" onblur="valid('input_bid',3)">
			秘钥类型（KeyType 1-keyA&nbsp;2-keyB）：<input type="text" id="input_keytype" onkeyup="value=value.replace(/\D/g,'')" oncontextmenu="return false;" onblur="valid('input_keytype',2)">
			秘钥（Key）：<input type="text" id="input_key">
		</td>
    </tr>
	<tr>
		<td >指令:<input type="text" id="cmd" size="49" style="width:400px;"></td>
	</tr>
	<tr>
      <td>结果：<textarea id="ACardResult" rows="8" cols="47" style="width:400px;" readonly="readonly"></textarea></td>
  </tr>
</table>
<table border="0" width="100%" cellpadding="0" cellspacing="10">
	<tr>
        <!--td><input type="button" value="读M1卡" onclick="readM1Card()"></td>
        <td><input type="button" value="写M1卡" onclick="writeM1Card()"></td>
        <td><input type="button" value="发送APDU指令" onclick="handleAPDUCMD()"></td-->
		<td>
			<input type="button" value="读M1卡"  onclick="readM1Card()">
			<input type="button" value="写M1卡"  onclick="writeM1Card()">
			<input type="button" value="发送APDU指令" onclick="handleAPDUCMD()">
		</td>
	</tr>
</table>

</body>
<script src="res/jquery.min.js"></script>
<script src="res/socket.js"></script>
<script type="text/javascript">
	
	//清空页面上显示的内容
  function clearForm() {
	//对应控件的值全部清空
    document.getElementById("timeElapsed").value = "";
    document.getElementById("certType").value = "";
    document.getElementById("timeElapsed").value = "";
    document.getElementById("venderId").value = "";
    document.getElementById("signature").value = "";
    document.getElementById("partyName").value = "";
    document.getElementById("gender").value = "";
    document.getElementById("nation").value = "";
    document.getElementById("bornDay").value = "";
    document.getElementById("certAddress").value = "";
    document.getElementById("certNumber").value = "";
    document.getElementById("certOrg").value = "";
    document.getElementById("effDate").value = "";
    document.getElementById("expDate").value = "";
    document.getElementById("HeadPic").src = "";
    document.getElementById("PhotoDisplay").src = "";
    document.getElementById("FrontPic").src = "";
    document.getElementById("BackPic").src = "";
	}

		// 清除窗口消息
		function clearMsg(){
			document.getElementById('message').innerHTML = "";
			clearForm();
		}

    var websocket = null;  

    //监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。  
    window.onbeforeunload = function () {  
        closeWebSocket();  
    };
		
		// 连接服务端
		function openWebSocket(){
			 var url = document.getElementById('url').value;  
			 //var token = document.getElementById('token').value;  
			if('WebSocket' in window) {
				//websocket = new WebSocket(url,[token]); 
				websocket = new WebSocket(url);
			} else if('MozWebSocket' in window) {
			    console.log("MozWebSocket");
				websocket = new MozWebSocket(url);
			} else {
				console.log("SockJS");
				//websocket = new SockJS("localhost:8088/websocket/webSocketByTomcat/"+document.getElementById('sessionId').value);
			}
			
			if(websocket == null)
			{
				alert("创建WebSocket对象失败");
			}
			
            //连接发生错误的回调方法
            websocket.onerror = function () {
                setMessageInnerHTML("WebSocket连接发生错误");
            };

            //连接成功建立的回调方法
            websocket.onopen = function () {
                setMessageInnerHTML("WebSocket连接成功");
            };

            //接收到消息的回调方法
            websocket.onmessage = function (event) {
                setMessageInnerHTML(event.data);
                
                var resultObj = eval('(' +event.data+')');
								//resultFlag为0代表读卡成功
								if (resultObj.name == "readCard" || resultObj.name == "readCert"
										|| resultObj.name == "PushWithImg" || resultObj.name == "PushWithOutImg")
								{
	                if (resultObj.resultFlag == "0") {
											//回显相关数据
	                    document.getElementById("signature").value = resultObj.signature;
	                    document.getElementById("venderId").value = resultObj.venderId;
	                    document.getElementById("certType").value = resultObj.resultContent.certType;
	                    document.getElementById("partyName").value = resultObj.resultContent.partyName;
	                    document.getElementById("gender").value = resultObj.resultContent.gender;
	                    document.getElementById("nation").value = resultObj.resultContent.nation;
	                    document.getElementById("bornDay").value = resultObj.resultContent.bornDay;
	                    document.getElementById("certAddress").value = resultObj.resultContent.certAddress;
	                    document.getElementById("certNumber").value = resultObj.resultContent.certNumber;
	                    document.getElementById("certOrg").value = resultObj.resultContent.certOrg;
	                    document.getElementById("effDate").value = resultObj.resultContent.effDate;
	                    document.getElementById("expDate").value = resultObj.resultContent.expDate;
	                    document.getElementById("HeadPic").src = "data:image/jpeg;base64," + resultObj.resultContent.identityPic;
	                    if (resultObj.name == "readCert" || resultObj.name == "PushWithImg")
	                    {
	                    	document.getElementById("PhotoDisplay").src = "data:image/jpeg;base64," + resultObj.resultContent.identityPrintPic;
	                    	document.getElementById("FrontPic").src = "data:image/jpeg;base64," + resultObj.resultContent.identityFrontPic;
	                    	document.getElementById("BackPic").src = "data:image/jpeg;base64," + resultObj.resultContent.identityBackPic;
	                    }
									} else if (resultObj.resultFlag == "-1") {
	                    if (resultObj.errorMsg == "端口打开失败") {
	                        //alert("读卡器未连接");
	                    } else {
	                        //alert(resultObj.errorMsg);
	                    }
	                } else if (resultObj.resultFlag == "-2") {
	                    //alert(resultObj.errorMsg);
	                }            
	              } 
	            	else if (resultObj.name == "getStatus")
	            	{
	            		if (resultObj.resultFlag == "0")
	            		{
	            			if (resultObj.status == "0")
	            			{
	            			}
	            			else
	            			{
	            				alert("设备连接已断开，请检查读卡器连接");
	            			}
	            		}
	            	}
	            	else if (resultObj.name == "readM1Card" || resultObj.name == "writeM1Card" || resultObj.name == "handleAPDUCMD") {
	            		document.getElementById("ACardResult").value = event.data;
	            	}
	              	
            };

            //连接关闭的回调方法
            websocket.onclose = function () {
                setMessageInnerHTML("WebSocket连接关闭");
            };
    }
		
    //将消息显示在网页上  
    function setMessageInnerHTML(text) {  
        document.getElementById('message').innerHTML = text;  
    }  
  
    //关闭WebSocket连接  
    function closeWebSocket() {  
        websocket.close();  
    }
    
    var timer = 0;
    
    function checkStatus()
		{
			var jsonObj = {
				"name":"getStatus"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
        
    // 开始定时检测连接
    function startCheckStatus(){
			timer = setInterval(checkStatus, 5000);
		}
		
		function stopCheckStatus(){
			clearInterval(timer);
			timer = 0;
		}        
		
		//连接设备
		function connect()
		{
			var jsonObj = {
				"name":"connect"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}

		//断开设备连接
		function disconnect()
		{
			var jsonObj = {
				"name":"disconnect"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//获取状态
		function getStatus()
		{
			var jsonObj = {
				"name":"getStatus"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//读卡
		function readCard()
		{
			var jsonObj = {
				"name":"readCard"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		//读卡
		function readCert()
		{
			var jsonObj = {
				"name":"readCert"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//获取IC卡序列号
		function readICCardSN()
		{
			var jsonObj = {
				"name":"readICCardSN"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//获取身份证物理卡号
		function readIDCardSN()
		{
			var jsonObj = {
				"name":"readIDCardSN"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//获取SAMID
		function getSAMID()
		{
			var jsonObj = {
				"name":"getSAMID"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		// 获取版本号
		function getVersion()
		{
			var jsonObj = {
				"name":"getVersion"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
				
		//开启推送（带图片)
		function startPushInfosWithImg()
		{
			var jsonObj = {
				"name":"openPush",
				"withImg": true
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}

		//开启推送（不带图片)
		function startPushInfosWithOutImg()
		{
			var jsonObj = {
				"name":"openPush",
				"withImg": false,
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//关闭推送
		function stopPushInfos()
		{
			var jsonObj = {
				"name":"closePush"
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		// 允许重复读卡
		function enableRepeatRead() {
			var jsonObj = {
				"name":"repeatRead",
				"isRepeatRead": true
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		// 禁止重复读卡
		function disableRepeatRead() {
			var jsonObj = {
				"name":"repeatRead",
				"isRepeatRead": false
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		// 开启静音
		function Routon_Mute() {
			var jsonObj = {
				"name":"mute",
				"isMute": true
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}

		// 关闭静音
		function Routon_UnMute() {
			var jsonObj = {
				"name":"mute",
				"isMute": false
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}		
		
		
		//读M1卡扇区内容
		function readM1Card() {
			var result = "";
			var sid = "1";
			var bid = "1";
			var keyType = "1";
			var key = "ffffffffffff";
			if(document.getElementById("input_sid").value != "")
			{
				sid = document.getElementById("input_sid").value;
			}
			
			if(document.getElementById("input_bid").value != "")
			{
				bid = document.getElementById("input_bid").value;
			}
			
			if(document.getElementById("input_keytype").value != "")
			{
				keyType = document.getElementById("input_keytype").value;
			}
			
			if(document.getElementById("input_key").value != "")
			{
				key = document.getElementById("input_key").value;
			}
			
			var jsonObj = {
				"name":"readM1Card",
				"params": {
					"SID": sid,
					"BID": bid,
					"KEYTYPE": keyType,
					"KEY": key
				}
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//写M1卡扇区内容
		function writeM1Card() {
			var result = "";
			var sid = "1";
			var bid = "1";
			var keyType = "1";
			var key = "ffffffffffff";
			var data = "00000000000000000000000000000000";
			if(document.getElementById("input_sid").value != "")
			{
				sid = document.getElementById("input_sid").value;
			}
			
			if(document.getElementById("input_bid").value != "")
			{
				bid = document.getElementById("input_bid").value;
			}
			
			if(document.getElementById("input_keytype").value != "")
			{
				keyType = document.getElementById("input_keytype").value;
			}
			
			if(document.getElementById("input_key").value != "")
			{
				key = document.getElementById("input_key").value;
			}
			
			if(document.getElementById("cmd").value != "")
			{
				data = document.getElementById("cmd").value;
			}
			
			var jsonObj = {
				"name":"writeM1Card",
				"params": {
					"SID": sid,
					"BID": bid,
					"KEYTYPE": keyType,
					"KEY": key,
					"DATA": data
				}
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}
		
		//处理CPU卡APDU指令
		function handleAPDUCMD(){
			//var cmd = "00A4000000"; //基本命令（测试用）：选择MF下的根目录，返回值为：6F15840E315041592E5359532E4444463031A5038801019000
			var cmd = "";
			if(document.getElementById("cmd").value != "")
			{
				cmd = document.getElementById("cmd").value;
			}
			var jsonObj = {
				"name":"handleAPDUCMD",
				"params": {
					"APDUCMD": cmd
				}
			};
			
			var jStr = JSON.stringify(jsonObj);
			
			websocket.send(jStr);
		}

    </script>
</html>